package com.fis.vaadin;

import java.util.LinkedHashMap;

import com.fis.mca.admin.AppClient;
import com.fss.dictionary.Dictionary;
import com.fss.util.StringUtil;
import com.vaadin.Application;
import com.vaadin.ui.Component;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

/**
 * Vaadin Form Builder<br/>
 * <b>Version: </b>1.0
 * 
 * @author MinhNX2@fpt.com.vn
 * @since Vaadin version 6.7.3
 * @category Vaadin Projects
 */
@SuppressWarnings("serial")
public class VaadinForm extends VerticalLayout implements AbstractVaadinForm {

	private final String RESOURCES_BASE = "ResourcesBase";
	private final String EXT_PROPERTIES = ".form";

	private VaadinFormBuilder vaadinFormBuilder;
	private VaadinFormData vaadinFormData;
	@SuppressWarnings("rawtypes")
	private static LinkedHashMap mapCache = new LinkedHashMap();

	/**
	 * Get the <b>VaadinFormBuilder</b> object using in builder process
	 * 
	 * @return com.fis.vaadin.VaadinFormBuilder object
	 * @throws Exception
	 */
	public VaadinFormBuilder getVaadinFormBuilder() throws Exception {

		if (vaadinFormBuilder == null)
			vaadinFormBuilder = new VaadinFormBuilderImpl(this);

		return vaadinFormBuilder;

	}

	protected VaadinForm() {

		vaadinFormData = new VaadinFormData();

	}

	/**
	 * Get the configuration base path configured in <b>ClientConfig.txt</b>
	 * file with property named <b>ResourceBase</b>
	 * 
	 * @return Configuration base path
	 * @throws Exception
	 */
	public final String getConfigBase() throws Exception {
		return AppClient.getSessionValue(RESOURCES_BASE);
	}

	/**
	 * Get the key using for get value in dictionary file.<br/>
	 * This key convert from class name to string
	 * 
	 * @return Key to get value in <b>dictionary</b>
	 * @throws Exception
	 */
	public final String getKey() throws Exception {
		return StringUtil.replaceAll(getClass().getName(), ".", "/");
	}

	/**
	 * Get all properties in configuration file converted to <b>Dictionary</b>
	 * object
	 * 
	 * @return com.fss.dictionary.Dictionary
	 * @throws Exception
	 */
	public final Dictionary getFormConfig() throws Exception {
		return Dictionary.getCachedDictionary(getConfigBase() + getKey()
				+ EXT_PROPERTIES, mapCache);
	}

	/**
	 * Get all properties and controls configuration, mapping etc.
	 * 
	 * @return com.fis.vaadin.VaadinFormData
	 * @throws Exception
	 */
	public final VaadinFormData getFormData() throws Exception {
		return vaadinFormData;
	}

	/**
	 * @param controlId
	 *            Control Identify in configure file.<br/>
	 *            For example <code>
	 * <pre>
	 * Width==500
	 * Height==400
	 * Field
	 * 	Tree==<b>itemTree</b>
	 * 		Width==50%
	 * 		Height==200px
	 * </pre>
	 * </code> Here, the <b>itemTree</b> is control Id
	 * @return com.vaadin.ui.Component
	 * @throws Exception
	 */
	public final Component getComponent(String controlId) throws Exception {

		return (Component) getFormData().getMapControlList().get(controlId);

	}

	public void backupFormData() throws Exception {
		vaadinFormData.backupFormData();
	}

	public void restoreFormData() throws Exception {
		vaadinFormData.restoreFormData();
	}

	public void clearBackupFormData() throws Exception {
		vaadinFormData.clearBackupFormData();
	}

	/**
	 * @return This class name
	 * @throws Exception
	 */
	public final String getModuleName() throws Exception {

		String strClass = getClass().getName();

		int iIndex = strClass.lastIndexOf(".");

		if (iIndex >= 0)
			strClass = strClass.substring(iIndex + 1, strClass.length());

		return strClass;
	}

	/**
	 * Protected method <b>buildForm</b> using to build new form from extend
	 * configuration file. A class must extends from <b>VaadinForm</b> class and
	 * call <b>buildForm</b> method to build with pre-configs.<br/>
	 * For example one file contains following configure to identify form
	 * structure and all components: <code>
	 * <pre>
	 * Width==500
	 * Height==400
	 * Field
	 * 	Tree==itemTree
	 * 		Width==50%
	 * 		Height==200px
	 * 	Button==btnAccept
	 * 		Icon==icons/16/cancel.jpg
	 * 		Resource==frmItem.field_name.caption
	 * 		Description==frmItem.field_name.caption
	 * 	Number==nbAmount
	 * 		ReadOnly==True
	 * 		Visible==True
	 * 	Slider==sldDemo
	 * 		Title==Slider Demo
	 * 		Width==100%
	 * Layout
	 * 	Panel==Grid
	 * 		AllowSpacing==True
	 * 		Margin==Top:Bottom:Left
	 * 		Row==2
	 * 		Column==4
	 * 		Layout
	 * 			Label==lblTree
	 * 				Width==100px
	 * 				Resource==frmItem.field_name.caption
	 * 				Icon==icons/16/cancel.jpg
	 * 			Control==itemTree
	 * 				Width==300px
	 * </pre>
	 * </code>
	 * 
	 * @author MinhNX2
	 * @since Vaadin version 6.7.3
	 * @category Vaadin Projects
	 * @throws Exception
	 *             , DuplicateException, InvokeException, NotfoundException,
	 *             UnsuppportedException
	 * 
	 */
	public final void buildForm() throws Exception {

		Dictionary dic = getFormConfig();

		if (dic != null)
			getVaadinFormBuilder().buildForm(this, vaadinFormData, dic);

	}

	public boolean isInputValidate() throws Exception {

		if (vaadinFormData == null)
			return true;

		Dictionary dic = getFormConfig();

		if (dic != null)
			return getVaadinFormBuilder().isValidate(this, vaadinFormData, dic);

		return false;
	}

	public boolean isInputValidate(String[] fields) throws Exception {
		if (vaadinFormData == null)
			return true;

		Dictionary dic = getFormConfig();

		if (dic != null)
			return getVaadinFormBuilder().isValidate(this, vaadinFormData, dic,
					fields);

		return false;
	}

	public boolean isInputValidateExclude(String[] fields) throws Exception {
		if (vaadinFormData == null)
			return true;

		Dictionary dic = getFormConfig();

		if (dic != null)
			return getVaadinFormBuilder().isValidateExclude(this,
					vaadinFormData, dic, fields);

		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.ui.AbstractComponent#getWindow()
	 */

	@Deprecated
	@Override
	public Window getWindow() {
		// TODO Auto-generated method stub
		return super.getWindow();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.vaadin.ui.AbstractComponent#getApplication()
	 */
	@Deprecated
	@Override
	public Application getApplication() {
		// TODO Auto-generated method stub
		return super.getApplication();
	}

}
